
' SceneTypes
Const ST_GENERIC:Int								= 1
Const ST_EXTERIOR_CLOSE:Int							= 2
Const ST_EXTERIOR_FAR:Int							= 4
Const ST_EXTERIOR_REAL_FAR:Int						= 8
Const ST_INTERIOR:Int								= 16


' ShadowTypes
Const SHADOWTYPE_NONE:Int							= $00
Const SHADOWDETAILTYPE_ADDITIVE:Int 				= $01
Const SHADOWDETAILTYPE_MODULATIVE:Int 				= $02
Const SHADOWDETAILTYPE_INTEGRATED:Int 				= $04
Const SHADOWDETAILTYPE_STENCIL:Int 					= $10
Const SHADOWDETAILTYPE_TEXTURE:Int 					= $20
Const SHADOWTYPE_STENCIL_MODULATIVE:Int 			= $12
Const SHADOWTYPE_STENCIL_ADDITIVE:Int 				= $11
Const SHADOWTYPE_TEXTURE_MODULATIVE:Int 			= $22
Const SHADOWTYPE_TEXTURE_ADDITIVE:Int 				= $21
Const SHADOWTYPE_TEXTURE_ADDITIVE_INTEGRATED:Int 	= $25
const SHADOWTYPE_TEXTURE_MODULATIVE_INTEGRATED:Int	= $26

' Fog Modes
Const FOG_NONE:Int									= 0
Const FOG_EXP:Int									= 1
Const FOG_EXP2:Int									= 2
Const FOG_LINEAR:Int								= 3


Type SceneManager Extends BaseObject
rem
bbdoc: Creates a camera to be managed by this scene manager. 
about: This camera must be added to the scene at a later time using the attachObject method of the SceneNode class. 
endrem
	Method createCamera:Camera(name:String = "")
		If name = "" Then name = Root.genName("camera_")
		Local cam:Camera = New Camera
		cam._ptr 		= o_createCamera(Self._ptr, name.ToCString())
		cam._typ 		= ET_CAMERA
		cam.vport		= New Viewport
		cam.vport._typ	= ET_NO_ENTITY
		cam.vport._ptr	= o_camera_getViewPort(cam._ptr)
		
		return cam
	End Method
	
rem
bbdoc: Create an Entity (instance of a discrete mesh). 
about: <b>Parameters:</b>
<table cellpadding="4" cellspacing="4" border="0">
<tr>
	<td><i>entityName</i></td><td>The name to be given to the entity (must be unique).</td>
</tr>
<tr>
	<td><i>meshName</i></td><td>The name of the Mesh it is to be based on (e.g. 'knot.oof'). The mesh will be loaded if it is not already.</td>
</tr>
</table>
endrem
	Method createEntity:Entity(entityName:String, meshName:String, groupName:String = AUTODETECT_RESOURCE_GROUP_NAME)
		Local ent:Entity = New Entity
		If Not entityName.Length Then entityName = Root.genName()
		ent._ptr = o_createEntity(Self._ptr, entityName.ToCString(), meshName.ToCString(), groupName.ToCString())
		ent._typ = ET_ENTITY
		
		Return ent
	End Method
	
rem
bbdoc: Gets the SceneNode at the root of the scene hierarchy. 
about: <p>The entire scene is held as a hierarchy of nodes, which allows things like relative transforms, general 
changes in rendering state etc (See the SceneNode class for more info). In this basic SceneManager  class, the 
application using Ogre is free to structure this hierarchy however it likes, since it has no real significance apart 
from making transforms relative to each node (more specialised subclasses will provide utility methods for building 
specific node structures e.g. loading a BSP tree).</p>
<p>However, in all cases there is only ever one root node of the hierarchy, and this method returns a pointer to it.</p>
endrem
	Method getRootSceneNode:SceneNode()
		Local node:SceneNode = New SceneNode
		Local pnode:Byte ptr = o_getRootSceneNode(Self._ptr)
		
		If node._list = Null
			node._list = New TList
			node._list.AddLast(node)
			node._ptr = pnode
			node._typ = ET_SCENENODE
		Else
			Local found:Byte = False
			For Local n:SceneNode = EachIn node._list
				If n._ptr = pnode
					node = n
					Exit
				End If
			Next
			
			If found = False
				node._list.AddLast(node)
				node._ptr = pnode;
				node._typ = ET_SCENENODE
			End If
		End If
		
		Return node
	End Method
	
rem
bbdoc: Creates a light for use in the scene. 
about: Lights can either be in a fixed position and independent of the scene graph, or they can be attached to 
SceneNodes so they derive their position from the parent node. Either way, they are created using this method so 
that the SceneManager  manages their existence. 
endrem
	Method createLight:Light()
		Local l:Light = New Light
		l._ptr	= o_createLight(Self._ptr)
		l._typ	= ET_LIGHT
		
		Return l
	End Method
	
rem
bbdoc: Sets the ambient light level to be used for the scene. 
about: <p>This sets the colour and intensity of the ambient light in the scene, i.e. the light which is 'sourceless' 
and illuminates all objects equally. The colour of an object is affected by a combination of the light in the scene, 
and the amount of light that object reflects (in this case based on the Material::ambient property).</p> 
<p>By default the ambient light in the scene is ColourValue::Black, i.e. no ambient light. This means that any objects 
rendered with a Material which has lighting enabled (see Material::setLightingEnabled) will not be visible unless you 
have some dynamic lights in your scene.</p>
endrem
	Method setAmbientLight(colour:ColourValue)
		o_setAmbientLight(self._ptr, colour.toC())
	End Method
	
rem
bbdoc: Removes a camera from the scene. 
about: This method removes a previously added camera from the scene. The camera is deleted so the caller must ensure no 
references to it's previous instance (e.g. in a SceneNode) are used. 
endrem
	Method destroyCamera(cam:Camera)
		o_destroyCamera(Self._ptr, cam._ptr)
	End Method
	
rem
bbdoc: Removes (and destroys) all cameras from the scene. 
about: Some cameras are internal created to dealing with texture shadow, their aren't supposed to destroy outside. 
So, while you are using texture shadow, don't call this method, or you can set the shadow technique other than 
texture-based, which will destroy all internal created shadow cameras and textures. 
endrem
	Method destroyAllCameras()
		o_destroyAllCameras(Self._ptr)
	End Method
	
rem
bbdoc: Removes the light from the scene and destroys it based on a pointer. 
about: Any pointers held to this light after calling this method will be invalid. 
endrem
	Method destroyLight(l:Light)
		o_destroyLight(Self._ptr, l._ptr)
	End Method
	
rem
bbdoc: Removes and destroys all lights in the scene. 
endrem
	Method destroyAllLights()
		o_destroyAllLights(Self._ptr)
	End Method
	
rem
bbdoc: Destroys a SceneNode. 
about: This allows you to physically delete an individual SceneNode if you want to. Note that this is not normally 
recommended, it's better to allow SceneManager  to delete the nodes when the scene is cleared. 
endrem
	Method destroySceneNode(node:SceneNode)
		o_destroySceneNode(Self._ptr, node._ptr)
	End Method
	
rem
bbdoc: Removes & destroys an Entity from the SceneManager. 
about: <b>Warning:</b> Must only be done if the Entity is not attached to a SceneNode. It may be safer to wait to clear 
the whole scene if you are unsure use clearScene. 
endrem
	Method destroyEntity(ent:Entity)
		o_destroyEntity(Self._ptr, ent._ptr)
	End Method
	
rem
bbdoc: Removes & destroys all Entities.
about: <b>Warning:</b> Again, use caution since no Entity must be referred to elsewhere e.g. attached to a SceneNode 
otherwise a crash is likely. Use clearScene if you are unsure (it clears SceneNode entries too.) 
endrem
	Method destroyAllEntities()
		o_destroyAllEntities(Self._ptr)
	End Method

rem
bbdoc: Sets the general shadow technique to be used in this scene. 
about: There are multiple ways to generate shadows in a scene, and each has strengths and weaknesses.
<ul>
<li>Stencil-based approaches can be used to draw very long, extreme shadows without loss of precision and the 'additive' 
version can correctly show the shadowing of complex effects like bump mapping because they physically exclude the light 
from those areas. However, the edges are very sharp and stencils cannot handle transparency, and they involve a fair amount 
of CPU work in order to calculate the shadow volumes, especially when animated objects are involved.
<li>Texture-based approaches are good for handling transparency (they can, for example, correctly shadow a mesh which uses 
alpha to represent holes), and they require little CPU overhead, and can happily shadow geometry which is deformed by a 
vertex program, unlike stencil shadows. However, they have a fixed precision which can introduce 'jaggies' at long range 
and have fillrate issues of their own.
</ul>
<p>We support 2 kinds of stencil shadows, and 2 kinds of texture-based shadows, and one simple decal approach. The 2 stencil 
approaches differ in the amount of multipass work that is required - the modulative approach simply 'darkens' areas in shadow 
after the main render, which is the least expensive, whilst the additive approach has to perform a render per light and adds 
the cumulative effect, whcih is more expensive but more accurate. The texture based shadows both work in roughly the same way, 
the only difference is that the shadowmap approach is slightly more accurate, but requires a more recent graphics card.</p>
<p>Note that because mixing many shadow techniques can cause problems, only one technique is supported at once. Also, you 
should call this method at the start of the scene setup.</p>
endrem
	Method setShadowTechnique(technique:Int)
		o_setShadowTechnique(Self._ptr, technique)
	End Method
	
rem
bbdoc: Set the size of the texture used for all texture-based shadows. 
about: <p>The larger the shadow texture, the better the detail on texture based shadows, but obviously this takes more memory. 
The default size is 512. Sizes must be a power of 2.</p>
<p><b>Note:</b> This is the simple form, see setShadowTextureConfig for the more complex form.</p>
endrem
	Method setShadowTextureSize(texsize:Int = 512)
		o_setShadowTextureSize(Self._ptr, texsize)
	End Method
	
rem
bbdoc: Sets whether when using a built-in additive shadow mode, user clip planes should be used to restrict light rendering. 
endrem
	Method setShadowUseLightClipPlanes(enable:Byte)
		o_setShadowUseLightClipPlanes(Self._ptr, enable)
	End Method
	
rem
bbdoc: Sets the default maximum distance away from the camera that shadows will be visible.
about: <p>You have to call this function before you create lights or the default distance of zero will be used.</p>
<p>Shadow techniques can be expensive, therefore it is a good idea to limit them to being rendered close to the camera if 
possible, and to skip the expense of rendering shadows for distance objects. This method allows you to set the distance 
at which shadows will no longer be rendered.</p>
<p><b>Note:</b> Each shadow technique can interpret this subtely differently. For example, one technique may use this 
to eliminate casters, another might use it to attenuate the shadows themselves. You should tweak this value to suit your 
chosen shadow technique and scene setup.</p>
endrem
	Method setShadowFarDistance(distance:Float)
		o_sm_setShadowFarDistance(Self._ptr, distance)
	End Method
	
rem
bbdoc: Enables / disables a 'sky box' i.e. a 6-sided box at constant distance from the camera representing the sky.
about: <p>You could create a sky box yourself using the standard mesh and entity methods, but this creates a plane which the 
camera can never get closer or further away from - it moves with the camera. (NB you could create this effect by creating 
a world box which was attached to the same SceneNode as the Camera too, but this would only apply to a single camera 
whereas this skybox applies to any camera using this scene manager).</p>
<p>The material you use for the skybox can either contain layers which are single textures, or they can be cubic textures, 
i.e. made up of 6 images, one for each plane of the cube. See the TextureUnitState class for more information.</p>
<p><b>Parameters:</b></p>
<table cellpadding="4" cellspacing="4" border="0">
<tr>
	<td>
		<i>enable</i>
	</td>
	<td>
		True to enable the skybox, false to disable it
	</td>
</tr>
<tr>
	<td>
		<i>materialName</i>
	</td>
	<td>
		The name of the material the box will use
	</td>
</tr>
	<td>
		<i>distance</i>
	</td>
	<td>
		Distance in world coorinates from the camera to each plane of the box. The default is normally OK.
	</td>
</tr>
<tr>
	<td>
		<i>drawFirst</i>
	</td>
	<td>
		If true, the box is drawn before all other geometry in the scene, without updating the depth buffer. 
		This is the safest rendering method since all other objects will always appear in front of the sky. 
		However this is not the most efficient way if most of the sky is often occluded by other objects. 
		If this is the case, you can set this parameter to false meaning it draws after all other geometry 
		which can be an optimisation - however you must ensure that the distance value is large enough that 
		no objects will 'poke through' the sky box when it is rendered.
	</td>
</tr>
<tr>
	<td>
		<i>orientation</i>
	</td>
	<td>
		Optional parameter to specify the orientation of the box. By default the 'top' of the box is deemed 
		to be in the +y direction, and the 'front' at the -z direction. You can use this parameter to rotate 
		the sky if you want.
	</td>
</tr>
<tr>
	<td>
		<i>groupName</i>
	</td>
	<td>
		the name of the resource group to which to assign the plane mesh. 
	</td>
</tr>
</table>
endrem
	Method setSkyBox(enable:Byte, materialName:String, distance:Float = 5000.0, drawFirst:Byte = True, orientation:bQuaternion = Null, groupName:String = AUTODETECT_RESOURCE_GROUP_NAME)
		If orientation <> Null
			o_setSkyBox(Self._ptr, enable, materialName.ToCString(), distance, drawFirst, orientation.toC(), groupName.ToCString())
		Else
			o_setSkyBox(Self._ptr, enable, materialName.ToCString(), distance, drawFirst, Null, groupName.ToCString())
		EndIf
	End Method
	
rem
bbdoc: Creates a RaySceneQuery  for this scene manager. 
about: <P>This Method creates a New instance of a Query Object For this scene manager, looking For Objects which 
fall along a ray. See SceneQuery And RaySceneQuery  For full details.</p>
<p>The instance returned from this method must be destroyed by calling SceneManager::destroyQuery when it is no 
longer required.</p>
endrem
	Method createRayQuery:RaySceneQuery(r:Ray, Mask:Int = 4294967295)
		Local rsq:RaySceneQuery = New RaySceneQuery
		rsq._ptr = o_createRayQuery(Self._ptr, r._ptr, Mask)
		rsq._typ = ET_NO_ENTITY
		
		Return rsq
	End Method
	
rem
bbdoc: Destroys a scene query of any type.
endrem
	Method destroyQuery(rayquery:RaySceneQuery)
		o_destroyQuery(Self._ptr, rayquery._ptr)
	End Method
End Type
